package com.gitee.yongzhuzl.commonutil.util.code.des;

import com.gitee.yongzhuzl.commonutil.util.equals.EqualsUtil;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.nio.charset.StandardCharsets;
import java.security.Key;

/**
 * description: 3DES加密工具类
 * @author 朱正磊
 * @date 2019-07-09 19:03:37
 */
public class DESUtil {

    /**
     * description: 3DES加密
     * @author 朱正磊
     * @date 2025-09-04 09:48:34
     * @param text 明文
     * @param secretKey 密钥（32位）
     * @return 返回密文
     */
    public static String encode(String text, String secretKey) {
        try {
            return encodeOrDecode(text, secretKey, Cipher.ENCRYPT_MODE);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * description: 3DES解密
     * @author 朱正磊
     * @date 2025-09-04 09:48:41
     * @param text 密文
     * @param secretKey 密钥（32位）
     * @return 返回明文
     */
    public static String decode(String text, String secretKey) {
        try {
            return encodeOrDecode(text, secretKey, Cipher.DECRYPT_MODE);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * description: 3DES加密 或 3DES解密
     * @author 朱正磊
     * @date 2025-09-04 09:44:19
     * @param text 明文 或 密文
     * @param secretKey 密钥（32位）
     * @param mode 模式
     * @return 返回密文 或 明文
     * @throws Exception 异常信息
     */
    public static String encodeOrDecode(String text, String secretKey, int mode) throws Exception {
        DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("desede");
        Key deskey = keyFactory.generateSecret(spec);
        Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
        IvParameterSpec ips = new IvParameterSpec(secretKey.substring(0, 8).getBytes());
        if (EqualsUtil.isEquals(mode, Cipher.ENCRYPT_MODE)) {
            cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
            byte[] encryptData = cipher.doFinal(text.getBytes(StandardCharsets.UTF_8));
            // Base64加密
            return Base64.encode(encryptData);
        } else if (EqualsUtil.isEquals(mode, Cipher.DECRYPT_MODE)) {
            cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
            // Base64解密
            byte[] decryptData = cipher.doFinal(Base64.decode(text));
            return new String(decryptData, StandardCharsets.UTF_8);
        }
        return null;
    }

}
